﻿@typeparam TItem where TItem : RealServer

<MDialog @bind-Value="Value"
         MaxWidth="800"
         Persistent>
    <MCard>
        <MCardTitle>
            <span class="text-h5">真实服务器配置</span>
            <MSpacer />
            <MButton Icon
                     OnClick="CloseDialog">
                <MIcon>mdi-close</MIcon>
            </MButton>
        </MCardTitle>

        <MCardText>
            <MRow>
                <MCol Cols="12" Md="6">
                    <MTextField @bind-Value="Item.IpAddress"
                                Label="IP地址"
                                Outlined
                                Dense
                                Required
                                Rules="_ipRules" />
                </MCol>
                <MCol Cols="12" Md="6">
                    <MTextField @bind-Value="Item.Port"
                                Label="端口"
                                Type="number"
                                Outlined
                                Dense
                                Required
                                Rules="_portRules" />
                </MCol>
            </MRow>

            <MRow>
                <MCol Cols="12" Md="6">
                    <MTextField @bind-Value="Item.Weight"
                                Label="权重"
                                Type="number"
                                Outlined
                                Dense
                                Required
                                Rules="_weightRules" />
                </MCol>
                <MCol Cols="12" Md="6">
                    <MSelect @bind-Value="_healthCheckType"
                             ItemText="item=>item"
                             ItemValue="item=>item"
                             Items="_healthCheckTypes"
                             Label="健康检查类型"
                             Outlined
                             Dense
                             />
                </MCol>
            </MRow>

            <!-- TCP健康检查 -->
            @if (Item.HealthCheck is TcpHealthCheck tcpCheck)
            {
                <MRow>
                    <MCol Cols="12">
                        <MCard Flat>
                            <MCardTitle>TCP健康检查配置</MCardTitle>
                            <MCardText>
                                <MRow>
                                    <MCol Cols="12" Md="6">
                                        <MTextField @bind-Value="tcpCheck.ConnectPort"
                                        Label="连接端口"
                                        Type="number"
                                        Outlined
                                        Dense
                                        Required
                                        Rules="_portRules" />
                                    </MCol>
                                    <MCol Cols="12" Md="6">
                                        <MTextField @bind-Value="tcpCheck.ConnectTimeout"
                                        Label="连接超时(秒)"
                                        Type="number"
                                        Outlined
                                        Dense
                                        Required
                                        Rules="_timeoutRules" />
                                    </MCol>
                                </MRow>
                                <MRow>
                                    <MCol Cols="12" Md="6">
                                        <MTextField @bind-Value="tcpCheck.RetryCount"
                                        Label="重试次数"
                                        Type="number"
                                        Outlined
                                        Dense
                                        Required
                                        Rules="_retryRules" />
                                    </MCol>
                                    <MCol Cols="12" Md="6">
                                        <MTextField @bind-Value="tcpCheck.DelayBeforeRetry"
                                        Label="重试间隔(秒)"
                                        Type="number"
                                        Outlined
                                        Dense
                                        Required
                                        Rules="_timeoutRules" />
                                    </MCol>
                                </MRow>
                            </MCardText>
                        </MCard>
                    </MCol>
                </MRow>
            }

            <!-- HTTP健康检查 -->
            @if (Item.HealthCheck is HttpHealthCheck httpCheck)
            {
                <MRow>
                    <MCol Cols="12">
                        <MCard Flat>
                            <MCardTitle>HTTP健康检查配置</MCardTitle>
                            <MCardText>
                                <MRow>
                                    <MCol Cols="12">
                                        <MTextField @bind-Value="httpCheck.UrlPath"
                                        Label="请求路径"
                                        Outlined
                                        Dense
                                        Required
                                        Rules="_requiredRules" />
                                    </MCol>
                                </MRow>
                                <MRow>
                                    <MCol Cols="12" Md="6">
                                        <MTextField @bind-Value="httpCheck.StatusCode"
                                        Label="期望状态码"
                                        Type="number"
                                        Outlined
                                        Dense
                                        Required
                                        Rules="_statusCodeRules" />
                                    </MCol>
                                    <MCol Cols="12" Md="6">
                                        <MTextField @bind-Value="httpCheck.ExpectResponse"
                                        Label="期望响应内容(可选)"
                                        Outlined
                                        Dense />
                                    </MCol>
                                </MRow>
                                <MRow>
                                    <MCol Cols="12" Md="6">
                                        <MTextField @bind-Value="httpCheck.ConnectTimeout"
                                        Label="连接超时(秒)"
                                        Type="number"
                                        Outlined
                                        Dense
                                        Required
                                        Rules="_timeoutRules" />
                                    </MCol>
                                    <MCol Cols="12" Md="6">
                                        <MTextField @bind-Value="httpCheck.DelayBeforeRetry"
                                        Label="重试间隔(秒)"
                                        Type="number"
                                        Outlined
                                        Dense
                                        Required
                                        Rules="_timeoutRules" />
                                    </MCol>
                                </MRow>
                            </MCardText>
                        </MCard>
                    </MCol>
                </MRow>
            }

            <!-- SSL健康检查 -->
            @if (Item.HealthCheck is SslHealthCheck sslCheck)
            {
                <MRow>
                    <MCol Cols="12">
                        <MCard Flat>
                            <MCardTitle>SSL健康检查配置</MCardTitle>
                            <MCardText>
                                <MRow>
                                    <MCol Cols="12" Md="6">
                                        <MTextField @bind-Value="sslCheck.ConnectPort"
                                        Label="连接端口"
                                        Type="number"
                                        Outlined
                                        Dense
                                        Required
                                        Rules="_portRules" />
                                    </MCol>
                                    <MCol Cols="12" Md="6">
                                        <MTextField @bind-Value="sslCheck.ExpectCn"
                                        Label="期望CN名称"
                                        Outlined
                                        Dense />
                                    </MCol>
                                </MRow>
                                <MRow>
                                    <MCol Cols="12" Md="6">
                                        <MTextField @bind-Value="sslCheck.ConnectTimeout"
                                        Label="连接超时(秒)"
                                        Type="number"
                                        Outlined
                                        Dense
                                        Required
                                        Rules="_timeoutRules" />
                                    </MCol>
                                    <MCol Cols="12" Md="6">
                                        <MTextField @bind-Value="sslCheck.DelayBeforeRetry"
                                        Label="重试间隔(秒)"
                                        Type="number"
                                        Outlined
                                        Dense
                                        Required
                                        Rules="_timeoutRules" />
                                    </MCol>
                                </MRow>
                            </MCardText>
                        </MCard>
                    </MCol>
                </MRow>
            }
        </MCardText>

        <MCardActions>
            <MSpacer />
            <MButton Color="primary"
            OnClick="SaveItem">
                <MIcon Left>mdi-content-save</MIcon>
                保存
            </MButton>
            <MButton Color="secondary"
            OnClick="CloseDialog">
                取消
            </MButton>
        </MCardActions>
    </MCard>
</MDialog>

@code {
    [Parameter]
    public bool Value { get; set; }

    [Parameter]
    public EventCallback<bool> ValueChanged { get; set; }

    [Parameter]
    public TItem Item { get; set; }

    [Parameter]
    public EventCallback<TItem> ItemChanged { get; set; }

    [Parameter]
    public EventCallback<TItem> OnSave { get; set; }

    private string healthCheckType = "TCP";
    private string _healthCheckType
    {
        get=> healthCheckType;
        set
        {
            if (value != healthCheckType)
            {
                healthCheckType = value;
                HandleHealthCheckTypeChange(value);
            }
        }
    }
    private List<string> _healthCheckTypes = new() { "TCP", "HTTP", "SSL" };

    // 验证规则
    private List<Func<string, StringBoolean>> _requiredRules = new()
    {
        value => string.IsNullOrWhiteSpace(value) ? "必填字段" : true
    };

    private List<Func<string, StringBoolean>> _ipRules = new()
    {
        value => string.IsNullOrWhiteSpace(value) ? "IP地址不能为空" : true,
        value => !System.Net.IPAddress.TryParse(value, out _) ? "请输入有效的IP地址" : true
    };

    private List<Func<int, StringBoolean>> _portRules = new()
    {
        value => value <= 0 || value > 65535 ?
            "端口必须是1-65535之间的数字" : true
    };

    private List<Func<int, StringBoolean>> _weightRules = new()
    {
        value => value <= 0 ? 
            "权重必须是正整数" : true
    };

    private List<Func<int, StringBoolean>> _timeoutRules = new()
    {
        value =>  value <= 0 ?
            "超时时间必须是正整数" : true
    };

    private List<Func<int, StringBoolean>> _retryRules = new()
    {
        value =>  value <= 0 ?
            "重试次数必须是正整数" : true
    };

    private List<Func<int, StringBoolean>> _statusCodeRules = new()
    {
        value => value < 100 || value > 599 ?
            "状态码必须是100-599之间的数字" : true
    };

    protected override void OnParametersSet()
    {
        base.OnParametersSet();
        
        // 初始化健康检查类型选择
        if (Item.HealthCheck != null)
        {
            _healthCheckType = Item.HealthCheck switch
            {
                TcpHealthCheck _ => "TCP",
                HttpHealthCheck _ => "HTTP",
                SslHealthCheck _ => "SSL",
                _ => "TCP"
            };
        }
        else
        {
            // 默认TCP检查
            Item.HealthCheck = new TcpHealthCheck 
            { 
                ConnectPort = Item.Port,
                ConnectTimeout = 3,
                RetryCount = 3,
                DelayBeforeRetry = 3
            };
            _healthCheckType = "TCP";
        }
    }

    private void HandleHealthCheckTypeChange(string newType)
    {
        if (newType == _healthCheckType) return;

        _healthCheckType = newType;
        
        Item.HealthCheck = newType switch
        {
            "HTTP" => new HttpHealthCheck 
            { 
                UrlPath = "/",
                StatusCode = 200,
                ConnectTimeout = 3,
                RetryCount = 3,
                DelayBeforeRetry = 3
            },
            "SSL" => new SslHealthCheck 
            { 
                ConnectPort = Item.Port,
                ConnectTimeout = 3,
                RetryCount = 3,
                DelayBeforeRetry = 3
            },
            _ => new TcpHealthCheck 
            { 
                ConnectPort = Item.Port,
                ConnectTimeout = 3,
                RetryCount = 3,
                DelayBeforeRetry = 3
            }
        };
    }

    private async Task SaveItem()
    {
        // 确保健康检查端口与服务器端口一致（除非特别指定）
        if (Item.HealthCheck is TcpHealthCheck tcp && tcp.ConnectPort == 0)
        {
            tcp.ConnectPort = Item.Port;
        }
        else if (Item.HealthCheck is SslHealthCheck ssl && ssl.ConnectPort == 0)
        {
            ssl.ConnectPort = Item.Port;
        }

        await OnSave.InvokeAsync(Item);
        await CloseDialog();
    }

    private async Task CloseDialog()
    {
        Value = false;
        await ValueChanged.InvokeAsync(Value);
    }
}